using System.Collections;      // 引入集合命名空间，用于协程等  
using System.Collections.Generic;  // 引入泛型集合命名空间  
using Cinemachine;
using TMPro;
using UnityEngine;               // 引入Unity引擎命名空间  

public class EntityFX : MonoBehaviour  // 定义一个名为EntityFX的类，继承自MonoBehaviour  
{
    private Player player;// 玩家
    // 精灵渲染器组件的引用  
    private SpriteRenderer sr;// 玩家精灵渲染

    [Header("文本弹出")]
    [SerializeField] private GameObject popUpTextpPrefab;

    [Header("相机抖动")]
    [SerializeField] private float shakeMultiplier;// 通过调整这个值，可以增大或减小抖动效果的强度  
    public Vector3 shakeSwordImpact;// 收剑 
    public Vector3 shakeHighDamage;// 受到高伤害 
    private CinemachineImpulseSource screenShake;// CinemachineImpulseSource是Cinemachine插件中的一个组件，用于生成和管理抖动效果  

    // 拖拽赋值字段，用于After Image特效  
    [Header("After image fx")]          // 自定义Header，用于分组显示  
    [SerializeField] private GameObject afterImagePrefab;  // 残影预制体  
    [SerializeField] private float colorLooseRate;         // 颜色松散率  
    [SerializeField] private float afterImageCooldown;     // 残影冷却时间  
    private float afterImageCooldownTimer;                // 残影冷却计时器  

    // 拖拽赋值字段，用于闪光特效  
    [Header("Flash Fx")]                // 自定义Header  
    [SerializeField] private Material hitMat;              // 碰撞材质  
    [Tooltip("切换材质时间")]            // Tooltip提供额外信息  
    [SerializeField] private float flashDuration = .2f;    // 闪光持续时间  
    private Material originalMat;        // 原始材质  

    // 拖拽赋值字段，用于疾病（异常状态）颜色  
    [Header("Ailment colors")]          // 自定义Header  
    [SerializeField] private Color[] chillColor;           // 冰冻颜色数组  
    [SerializeField] private Color[] igniteColor;          // 点燃颜色数组  
    [SerializeField] private Color[] shockColor;           // 电击颜色数组  

    // 拖拽赋值字段，用于疾病（异常状态）粒子特效  
    [Header("Ailment particles")]       // 自定义Header  
    [SerializeField] private ParticleSystem igniteFX;      // 点燃粒子特效  
    [SerializeField] private ParticleSystem chillFX;       // 冰冻粒子特效  
    [SerializeField] private ParticleSystem shockFX;       // 电击粒子特效  

    // 拖拽赋值字段，用于碰撞特效  
    [Header("Hit FX")]                  // 自定义Header  
    [SerializeField] private GameObject hitFx;             // 普通碰撞特效  
    [SerializeField] private GameObject criticalHitFx;     // 暴击碰撞特效  

    // 空格，用于在Inspector面板中增加间隔  
    [Space]
    [SerializeField] private ParticleSystem dustFx;        // 灰尘粒子特效  

    // Start方法，在对象实例化时调用  
    private void Start()
    {
        player = PlayerManager.instance.player;            //获取玩家
        sr = GetComponentInChildren<SpriteRenderer>();     // 获取子对象中的SpriteRenderer组件  
        screenShake = GetComponent<CinemachineImpulseSource>();
        originalMat = sr.material;                        // 保存原始材质  
    }

    // Update方法，每帧调用  
    private void Update()
    {
        afterImageCooldownTimer -= Time.deltaTime;        // 冷却计时器递减  
    }

    // 创建弹出文本
    public void CreatePopUpText(string _text)
    {
        float randomX = Random.Range(1, -1);
        float randomY = Random.Range(1.5f, 3);
        Vector3 positionOffset = new Vector3(randomX, randomY, 0);
        GameObject newText = Instantiate(popUpTextpPrefab, transform.position + positionOffset, Quaternion.identity);
        newText.GetComponent<TextMeshPro>().text = _text;
    }

    // 相机抖动
    public void ScreenShake(Vector3 _shakePower)
    {
        // 设置CinemachineImpulseSource的默认速度（m_DefaultVelocity）  
        // 我们将shakeSwordImpact与player的facingDir（面向方向）和shakeMultiplier（倍率）相结合来计算抖动速度  
        // shakeMultiplier用于全局调整抖动效果的强度  
        screenShake.m_DefaultVelocity = new Vector3(_shakePower.x * player.facingDir, _shakePower.y) * shakeMultiplier;

        // 调用GenerateImpulse方法生成抖动效果  
        // 这个方法会根据m_DefaultVelocity和其他设置（如抖动时长等）来生成一个抖动动画  
        screenShake.GenerateImpulse();
    }

    // 创建残影方法  
    public void CreateAfterImage()
    {
        if (afterImageCooldownTimer < 0)                  // 如果冷却时间结束  
        {
            afterImageCooldownTimer = afterImageCooldown; // 重置冷却计时器  
            // 实例化残影预制体，并设置位置和旋转  
            GameObject newAfterIamge = Instantiate(afterImagePrefab, transform.position, transform.rotation);
            newAfterIamge.GetComponent<AfterIamgeFX>().SetupAfterImage(colorLooseRate, sr.sprite); // 设置残影参数  
        }
    }

    // 协程切换材质方法  
    private IEnumerator FlashFx()
    {
        sr.material = hitMat;                             // 切换材质  
        Color currenColor = sr.color;                     // 保存当前颜色  
        sr.color = Color.white;                           // 设置为白色  
        yield return new WaitForSeconds(flashDuration);   // 等待指定时间  
        sr.material = originalMat;                        // 恢复原始材质  
        sr.color = currenColor;                           // 恢复颜色  
    }

    // 红闪方法  
    private void RedColorBlink()
    {
        sr.color = sr.color == Color.white ? Color.red : Color.white; // 切换红色和白色  
    }

    // 取消红闪方法  
    private void CancelColorChange()
    {
        CancelInvoke();                                  // 取消所有Invoke调用  
        sr.color = Color.white;                           // 恢复白色  
        igniteFX.Stop();                                  // 停止点燃粒子特效  
        chillFX.Stop();                                   // 停止冰冻粒子特效  
        shockFX.Stop();                                   // 停止电击粒子特效  
    }

    // 设置透明度方法  
    public void MakeTransprent(bool _transprent)
    {
        sr.color = _transprent ? Color.clear : Color.white; // 根据参数设置透明度  
    }

    #region 元素特效方法  
    // 火特效方法  
    public void igniteFxFor(float _seconds)
    {
        igniteFX.Play();                                 // 播放点燃粒子特效  
        InvokeRepeating("IgniteColorFx", 0, .3f);        // 重复调用更换颜色方法  
        Invoke("CancelColorChange", _seconds);           // 在指定时间后取消颜色变化  
    }

    private void IgniteColorFx()
    {
        sr.color = sr.color == igniteColor[0] ? igniteColor[1] : igniteColor[0]; // 切换点燃颜色  
    }

    // 冰特效方法  
    public void ChillFxFor(float _seconds)
    {
        chillFX.Play();                                  // 播放冰冻粒子特效  
        InvokeRepeating("ChillColorFx", 0, .3f);         // 重复调用更换颜色方法  
        Invoke("CancelColorChange", _seconds);           // 在指定时间后取消颜色变化  
    }

    private void ChillColorFx()
    {
        sr.color = sr.color == chillColor[0] ? chillColor[1] : chillColor[0]; // 切换冰冻颜色  
    }

    // 电特效方法  
    public void ShockFxFor(float _seconds)
    {
        shockFX.Play();                                  // 播放电击粒子特效  
        InvokeRepeating("ShockColorFx", 0, .3f);         // 重复调用更换颜色方法  
        Invoke("CancelColorChange", _seconds);           // 在指定时间后取消颜色变化  
    }

    private void ShockColorFx()
    {
        sr.color = sr.color == shockColor[0] ? shockColor[1] : shockColor[0]; // 切换电击颜色  
    }
    #endregion

    // 创建攻击特效方法  
    public void CreatHitFx(Transform _target, bool _critical)
    {
        // 随机生成位置和旋转角度  
        float zRotation = Random.Range(-90, 90);
        float xPosition = Random.Range(-.5f, .5f);
        float yPosition = Random.Range(-.5f, .5f);
        Vector3 hitFxRotation = new Vector3(0, 0, zRotation);

        GameObject hitPrefab = _critical ? criticalHitFx : hitFx; // 根据是否暴击选择特效预制体  
        if (_critical)
        {
            zRotation = Random.Range(-45, 45); // 暴击时缩小z轴旋转角度范围  
            int yRotation = GetComponent<Entity>().facingDir == -1 ? 180 : 0; // 根据面向方向设置y轴旋转  
            hitFxRotation = new Vector3(0, yRotation, zRotation);
        }

        // 实例化特效，设置位置和旋转，并在0.5秒后销毁  
        GameObject newHitFx = Instantiate(hitPrefab, _target.position + new Vector3(xPosition, yPosition, 0), Quaternion.identity);
        // GameObject newHitFx = Instantiate(hitPrefab, _target.position + new Vector3(xPosition, yPosition, 0), Quaternion.identity, _target);
        newHitFx.transform.Rotate(hitFxRotation);
        Destroy(newHitFx, .5f);
    }

    // 播放灰尘特效方法、收回剑的时候  
    public void PlayDustFX()
    {
        if (dustFx != null)
            dustFx.Play(); // 如果灰尘特效不为空，则播放  
    }

}